<html>

	<head>
		<title>DeviceOrientationEvent</title>
		<meta charset="UTF-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
		<!--<script src="util/jibu.js" type="text/javascript" charset="utf-8"></script>-->
		<style type="text/css">
			.www {
				width: 100px;
				height: 50px;
				text-align: center;
				line-height: 50px;
				font-size: 18px;
				background: green;
				color: #fff;
				margin: 100px auto;
			}
		</style>
	</head>

	<body>
		<h1>我的计步</h1>
		<div id="jiasudu3">

		</div>
	</body>

</html>

<script>
	var resultX = 31; //xy坐标
	var resultY = 13; //xy坐标
	//FengZhuangXY();

	//状态：静止
	var STAY = 0;
	//状态：运动
	var MOVE = 1;
	//运动状态判断数组，长度20
	var stateValue = new Array(20).fill(0);
	//加速度数组  长度100
	var Accs = new Array(100).fill(0);;
	//每次传入加速度的时间，省去定时器 长度100
	var time = new Array(100).fill(0);
	//数组下标
	var count = 0;
	//行走步数
	var Step = 0;
	//步长
	var Length = 0;

	//行进距离
	var Distance = 0;
	var RDistance = 0;
	//状态
	var State = STAY;;

	var Ldirection = ''; //浏览器方向
	var direction;

	var AccelerometerX, AccelerometerY, AccelerometerZ; //加速计三个方向的数据
	var count = 0;
	var responseObj = {};
	var wobushu;

	try {
		var text = "";
		window.addEventListener("deviceorientation", orientationHandler, false);

		function orientationHandler(event) {
			text = ""
			direction = Math.round(event.alpha)
			Ldirection = 360 - Math.round(event.alpha);
			Ldirection += 180; //地图的0度和获取的度数相反
			Ldirection += 3; //获取的度数和地图偏差角

			if(Ldirection >= 360) {
				Ldirection -= 360;
			}
			//			var arrow = document.getElementById("arrow");
			//			text += "左右旋转：rotate alpha{" + direction + "deg)<p>";
			//			text += "左右旋转：rotate alpha{" + direction + "deg)<p>";
			//			text += "前后旋转：rotate beta{" + Ldirection + "deg)<p>";
			//			text += "扭转设备：rotate gamma{" + Ldirection + "deg)<p>";
			//			arrow.innerHTML = text;
		}
	} catch(e) {
		//		$("#arrow").html(e.message)
	}

	if(window.DeviceMotionEvent) {
		window.addEventListener('devicemotion', deviceMotionHandler, false);
	}
	var vibrateSupport = "vibrate" in navigator
	if(vibrateSupport) { //兼容不同的浏览器
		navigator.vibrate = navigator.vibrate || navigator.webkitVibrate || navigator.mozVibrate || navigator.msVibrate;
	}

	function deviceMotionHandler(eventData) {
		var acceleration = eventData.accelerationIncludingGravity;
		AccelerometerX = acceleration.x;
		AccelerometerY = acceleration.y;
		AccelerometerZ = acceleration.z;

		//		var jtext = ''
		//		var jiasudu = document.getElementById("jiasudu");
		//		jtext += "x方向：" + AccelerometerX + "<p>";
		//		jtext += "y方向：" + AccelerometerY + "<p>";
		//		jtext += "z方向：" + AccelerometerZ + "<p>";
		//		jtext += "resultX：" + resultX + "<p>";
		//		jtext += "resultY：" + resultY + "<p>";
		//
		//		jiasudu.innerHTML = jtext;

		var currentTime = getCurrentTime();
		var valuesArray = [acceleration.x, acceleration.y, acceleration.z];
		refreshAcc(valuesArray, currentTime);

	}

	function refreshAcc(values, timestamp) {
		Accs[count] = Math.sqrt(values[0] * values[0] + values[1] * values[1] + values[2] * values[2]);
		time[count] = timestamp;
		//检查运动状态
		stateValue[count % 20] = Accs[count];
		checkState();
		//设置检测点，检测点的值为到最新数据的距离，如果太近了将无法确定其为波峰波谷
		//检测点的作用是来减少计算量
		var ckpoint = Accs.length / 5;
		//运动状态判断加上判断检测点是否有波谷存在
		if(State == MOVE && Accs[(count - ckpoint + Accs.length) % Accs.length] < Accs[(count - ckpoint + Accs.length + 1) % Accs.length] &&
			Accs[(count - ckpoint + Accs.length) % Accs.length] <
			Accs[(count - ckpoint + Accs.length - 1) % Accs.length]) {
			//求均值
			var ave0 = 0;
			for(var i = 0; i < Accs.length; ++i) {
				ave0 += Accs[i];
			}
			ave0 /= Accs.length;
			//调整数组顺序，把新数据放在前面，同时把数据减去均值

			var data = new Array(Accs.length).fill(0);
			for(var i1 = 0, j = count; i1 < data.length; ++i1, --j) {
				if(j < 0) {
					j += data.length
				};
				data[i1] = Accs[j] - ave0;
			}
			//寻找波峰波谷
			var sign = new Array(Accs.length).fill(0);
			for(var i2 = 1; i2 < Accs.length - 1; ++i2) {
				if(Math.abs(data[i2]) > 0.8 &&
					Math.abs(2 * data[i2]) > Math.abs((data[i2 - 1] + data[i2 + 1]))) {
					if(data[i2] > 0) {
						sign[i2] = 1;
					} else {
						sign[i2] = -1;
					}
				}
			}

			for(var i3 = 1; i3 < sign.length - 1;) {
				var idx = i3;
				while(++i3 < sign.length - 1 &&
					(sign[i3] == 0 || sign[i3] == sign[idx])) {
					if(sign[i3] != 0 && Math.abs(data[i3]) > Math.abs(data[idx])) {
						sign[idx] = 0;
						idx = i3;
					} else {
						sign[i3] = 0;
					}
				}
			}
			//再次判断检测点是否是波谷
			if(sign[ckpoint] < 0) {
				var index = ckpoint;
				//寻找下个波峰
				while(++index < sign.length && sign[index] == 0);
				if(index < sign.length && sign[index] > 0) {
					var peak = index;
					//寻找下个波谷
					while(++index < sign.length && sign[index] == 0);
					if(index < sign.length && sign[index] < 0) {
						var valley = index;
						//计算H和T
						var H = data[peak] - 0.5 * data[ckpoint] - 0.5 * data[valley];
						var T = time[(count - ckpoint + time.length) % time.length] - time[(count - valley + time.length) % time.length];

						//门限判决
						if(H > 3 && T > 300 && T < 1400) {
							// if (H > 2 && T > 300 && T < 1400) {
							//步长计算
							var steplength = 0.35 - 0.000155 * T + 0.1638 * Math.sqrt(H);
							Length = (Length + steplength) / 2;
							Distance += steplength;
							++Step;
							console.log('Step', Step)

							//							var jtext = ''
							//							var jiasudu = document.getElementById("jiasudu2");
							//							jtext += "步数：" + Step + "<p>";
							//
							//							jiasudu.innerHTML = jtext;
							suanXY(resultX, resultY, steplength, direction)
						}
					}
				}
			}
		}
		if(++count == 100) count = 0;

	}

	//检查运动状态
	function checkState() {
		var ave = 0;
		var Var = 0;
		//求均值
		for(var i = 0; i < stateValue.length; i++) {
			ave += stateValue[i];
		}
		ave /= stateValue.length;
		//求方差
		for(var i = 0; i < stateValue.length; i++) {
			Var += (stateValue[i] - ave) * (stateValue[i] - ave);
		}
		Var /= stateValue.length;
		//状态判决
		State = Var > 0.5 ? MOVE : STAY;
	}

	//获取当前时间戳
	function getCurrentTime() {
		var timestamp = new Date().getTime();
		return timestamp;
	}

	function suanXY(coordinateX, coordinateY, currentStepLength, cDirection) {
		resultX = parseFloat(coordinateX) + parseFloat(currentStepLength * Math.sin(Math.PI / 180 * cDirection));
		resultY = parseFloat(coordinateY) + parseFloat(currentStepLength * Math.cos(Math.PI / 180 * cDirection));
				var jtext = ''
				var jiasudu = document.getElementById("jiasudu3");
				jtext += "坐标x：" + resultX + "<p>";
				jtext += "坐标y：" + resultY + "<p>";
		
				jiasudu.innerHTML = jtext;

	}
</script>